package org.jeecg.modules.innerApi.bwgfApi.convert;

import com.baiwang.open.entity.request.OutputInvoiceIssueRequest;
import com.baiwang.open.entity.request.node.OutputInvoiceIssueInvoiceDetail;
import com.baiwang.open.entity.request.node.OutputInvoiceIssuePreInvoice;
import com.baiwang.open.entity.response.OutputInvoiceIssueResponse;
import com.baiwang.open.entity.response.node.OutputInvoiceIssueInvoiceResult;
import org.apache.commons.lang.StringUtils;
import org.jeecg.common.util.DateUtils;
import org.jeecg.modules.common.util.MathUtil;
import org.jeecg.modules.innerApi.common.requestDto.InvoiceParam;
import org.jeecg.modules.innerApi.common.responseDto.InvoiceRtn;
import org.jeecg.modules.xxgx.common.enums.HsbzEnum;

import java.text.ParseException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public class BwRequestParamConvert {
    /**
     * 发票开具传入参数转换
     * @param page
     * @return
     */
    public static OutputInvoiceIssueRequest invoiceParamConvert(InvoiceParam page){
        OutputInvoiceIssueRequest request = new OutputInvoiceIssueRequest();

        request.setTaxNo(page.getKpzd().getNsrsbh());//税号
        request.setTaxUserName(page.getKpzd().getDzswjzh());//登录名，用于一税号多账户区分用，该登录名为税局页面登录名
        request.setInvoiceTerminalCode(page.getKpzd().getZddm());//开票终端代码。
        request.setIsSplit(false);//超过发票单张限额是否需要拆分开具，默认不拆分
        request.setOrgCode("");//组织机构编码
        request.setTaxDiskNo("");//设备编号，即盘号，包括税控盘，航信盘，自持ukey。
        request.setFormatGenerate(false);//是否需要生成版式返回版式链接(true / false);此参数仅对税控类开具的电子发票生效
        request.setFormatPushType(false);//版式生成是否推送(true / false)
        request.setCompletionCustom("0");//为（1/0 1 需要补全 0不需要补全，默认为0）是否根据客户编码，购方税号，购方名称查询客户信息补全未填写的购方信息

        OutputInvoiceIssuePreInvoice invoice = new OutputInvoiceIssuePreInvoice();
        invoice.setInvoiceTypeCode(page.getFplxdm());//发票种类编码
        invoice.setPaperInvoiceFlag(page.getZzfpbz());// 全电纸质发票标志（Y是N否），为Y时，invoiceSpecialMark特殊票种只能为00：普通发票，当invoiceTypeCode=01/02时，默认N； 税控类发票开具不校验此字段；
        invoice.setPaperInvoiceTypeCode(page.getZpfppzdm());//选择纸质发票标志为Y时，纸票类型必填。
        invoice.setInvoiceType(page.getKplx());//开票类型 0:正数发票（蓝票） 1：负数发票（红票）默认0
        invoice.setInvoiceSpecialMark(page.getTspz());//特殊票种标志
        invoice.setIsConfirmIssue("");//成品油单价过低是否确认开具标识：Y 是； N 否 为空时默认值为N
        invoice.setTaxationMethod(page.getZsfs());//征税方式， 0：普通征税；2：差额征税（默认是0普通征税）
        invoice.setTaxationLabel("");//差额征税标签：01 全额开票、 02 差额开票 ；发票类型代码为01，02时且征税方式为2必填
        invoice.setInvoiceListMark("");//0：无清单；1：带清单（专普票发票明细大于等于8行必须带清单）：大于8行必须为清单票(电子票只能为非请单票)（默认是0无清单），发票类型代码为01，02时该字段无
        //invoice.setPriceTaxMark(page.getHsbz());//含税标志， 0：不含税；1：含税（默认不含税）
        invoice.setPriceTaxMark("1");//含税标志， 0：不含税；1：含税（默认不含税）
        invoice.setSerialNo(page.getFpsqlsh());//开票流水号， 唯一标志开票请求。支持数字字母下划线组合。
        invoice.setBuyerTaxNo(page.getKhsh());//购方单位税号
        invoice.setBuyerName(page.getKhmc());//购方单位名称

        invoice.setBuyerAddressPhone(page.getKhdzdh());//购方地址及电话， 增值税专用发票开具时必填，发票类型代码为01、02时该字段拆分为地址电话两个字段
        invoice.setBuyerBankAccount(page.getKhyhzh());//购方开户行及账号， 增值税专用发票开具时必填，发票类型代码为01、02时该字段拆分为银行名称、账号两个字段
        invoice.setBuyerAddress(page.getKhdz());
        invoice.setBuyerTelphone(page.getKhdh());
        invoice.setBuyerBankName(page.getKhyh());
        invoice.setBuyerBankNumber(page.getKhzh());

        invoice.setDrawer(StringUtils.isEmpty(page.getKpr())?page.getKpzd().getKpr():page.getKpr());//开票人
        invoice.setChecker(page.getFhr());//复核人
        invoice.setPayee(page.getSkr());//收款人
        invoice.setInvoiceTotalPrice((page.getHjje()));//合计金额， 保留两位小数；支持价税分离
        invoice.setInvoiceTotalTax(page.getHjse());//合计税额
        invoice.setInvoiceTotalPriceTax(MathUtil.add(page.getHjje(),page.getHjse()));//价税合计
        invoice.setRemarks(page.getBz());//备注 乐企长度为230个字符
        invoice.setRedInfoNo(page.getHzxxbbh());//红字信息表/确认单编号，仅invoiceType=1时需要传入数据 税控类红票开具时，invoiceTypeCode=004、028时必须传值，传入红字信息表编号； 全电类红票开具时，invoiceTypeCode=01、02时必须传值，传入红字确认单编号；
        invoice.setOriginalInvoiceCode(page.getYfpdm());//原发票代码， invoiceType=1，负数票开具时必传
        invoice.setOriginalInvoiceNo(page.getYfphm());//原发票号码， invoiceType=1，负数票开具时必传;原全电发票号码
        invoice.setDeductibleAmount(page.getKce());//扣除额， taxationMode=2，差额征税时必传。数值必须小于价税合计。
        invoice.setSellerAddressPhone(page.getKpzd().getXfdz() + page.getKpzd().getXfdh());//销方地址及电话，发票类型代码为01、02时该字段拆分为地址、电话两个字段
        invoice.setSellerBankAccount(page.getKpzd().getXfyh() + page.getKpzd().getXfyhzh());//销方开户行及账号，发票类型代码为01、02时不用此字段
        invoice.setSellerAddress(page.getKpzd().getXfdz());//销方地址，发票类型代码为01、02时该字段可用
        invoice.setSellerTelphone(page.getKpzd().getXfdh());//销方电话，发票类型代码为01、02时该字段可用
        invoice.setSellerBankName(page.getKpzd().getXfyh());//销方银行名称，发票类型代码为01、02时该字段可用
        invoice.setSellerBankNumber(page.getKpzd().getXfyhzh());//销方银行账号，发票类型代码为01、02时该字段可用

        invoice.setSystemName("");//第三方系统名称
        invoice.setSystemId("");//第三方系统id
        invoice.setBuyerEmail(page.getKhlxyx());//客户邮箱
        invoice.setEmailCarbonCopy("");//抄送人邮箱,多个用英文逗号隔开,最多5个抄送人信息 全电字符长度为200
        invoice.setBuyerPhone(page.getKhlxfs());//客户电话
        invoice.setUserAccount("");//用户账号，用于个人维度数据标记
        invoice.setRedIssueReason(page.getHcyy());//红冲原因（1 销货退回 2 开票有误 3 服务终止 4 销售折让）税控红冲原因：建议按实际开票情况传入红冲原因，若不传系统会自动根据情况判断并赋值；全电红冲原因：必填
        invoice.setDiscountType("");//整单折扣类型 1 :按折扣金额价内折扣,2:按折扣金额价外折扣,3:按折扣率价内折扣,4:按折扣率价外折扣
        //invoice.setDiscountAmount(null);//整单折扣金额,大于0小于发票总金额，如果是含税发票，大于0小于含税总金额
        //invoice.setDiscountRate(null);//整单折扣率,取值[1-100]正整数
        invoice.setMainGoodsName("");//卷式发票票样 01 02 03 04 05 06 07

        invoice.setRedConfirmUuid("");//jxw todo:待确认  红字信息表UUID，开具全电负数发票必传
        invoice.setContractNumber("");//合同号
        invoice.setVoucherNo("");//凭证号
        invoice.setBuyerNaturalPerson("");//购买方自然人标记,Y：自然人 N：非自然人 ，默认为空
        invoice.setDisplayBuyer(false);//购方开户行银行账号是否显示在备注，true：购方开户行银行账号显示在备注，或者false：购方开户行银行账号不显示在备注
        invoice.setDisplaySeller(false);//销方开户行银行账号是否显示在备注。true：销方开户行银行账号显示在备注，或者false：销方开户行银行账号不显示在备注

        request.setData(invoice);

        List<OutputInvoiceIssueInvoiceDetail> invoiceDetailList = new ArrayList<>();

        page.getFpmxs().forEach(djmx -> {
            OutputInvoiceIssueInvoiceDetail invoiceDetail = new OutputInvoiceIssueInvoiceDetail();
            invoiceDetail.setGoodsLineNo(djmx.getMxhh());//明细行号
            invoiceDetail.setOriginalInvoiceDetailNo("1"); //jxw todo: 对应蓝票明细行号 税控类红字发票开具时无需传值； 全电类红字发票开具时必须传值；
            invoiceDetail.setInvoiceLineNature(StringUtils.isEmpty(djmx.getFphxz())?"0":djmx.getFphxz());//发票行性质， 0：正常行；1：折扣行；2：被折扣行，默认为0
            invoiceDetail.setGoodsCode(djmx.getSpbm());//税收分类编码（末级节点）
            invoiceDetail.setGoodsPersonalCode(djmx.getSpdm());//商品编码， 可以支持根据商品名称或商品编码进行获取【增加商品编码字段】：平台必须维护商品信息
            invoiceDetail.setGoodsName(djmx.getSpmc());//商品名称
            invoiceDetail.setGoodsSpecification(djmx.getGgxh());//规格型号
            invoiceDetail.setGoodsUnit(djmx.getJldw());//计量单位
            invoiceDetail.setGoodsQuantity(djmx.getSpsl());//商品数量
            if(HsbzEnum.Y.getValue().equals(page.getHsbz())){
                invoiceDetail.setGoodsPrice(djmx.getHsdj());
                invoiceDetail.setGoodsTotalPrice(djmx.getHsje());
            } else {
                invoiceDetail.setGoodsPrice(djmx.getBhsdj());
                invoiceDetail.setGoodsTotalPrice(djmx.getBhsje());
            }
            invoiceDetail.setGoodsTotalTax(djmx.getTaxje());//税额
            invoiceDetail.setGoodsTaxRate(djmx.getTax());//税率
            invoiceDetail.setVatSpecialManagement(djmx.getYhzcbs());//优惠政策类型，preferentialMarkFlag=1，使用优惠政策时必传，如“免税”、“50%先征后退”、“即征即退50%”等
            invoiceDetail.setFreeTaxMark(djmx.getLslbs());//零税率标识：空 代表不使用零税率； 1：出口免税和其他免税优惠政策； 2：不征增值税；3：普通零税率
            invoiceDetail.setPreferentialMarkFlag(djmx.getYhzcbs());// 优惠政策类型  是否使用优惠政策， 0：未使用；1：使用 根据商品信息获取
            invoiceDetail.setGoodsDiscountAmount(djmx.getZkje());//明细行折扣金额,全电不支持该字段

            invoiceDetailList.add(invoiceDetail);
        });

        invoice.setInvoiceDetailsList(invoiceDetailList);


        return request;
    }

    /**
     * 发票开具返回参数转换
     * @param response
     * @return
     */
    public static InvoiceRtn invoiceReturnConvert(OutputInvoiceIssueResponse response){
        InvoiceRtn invoiceRtn = new InvoiceRtn();

        if(response.getSuccess()) {
            InvoiceRtn.InvoiceRtnData invoiceRtnData = new InvoiceRtn.InvoiceRtnData();
            List<OutputInvoiceIssueInvoiceResult> list = response.getResponse().getSuccess();
            if(list.size() > 0){//调用接口一次只开一张发票
                OutputInvoiceIssueInvoiceResult result = list.get(0);
                invoiceRtnData.setFpdm(result.getInvoiceCode());//发票代码
                invoiceRtnData.setFphm(result.getInvoiceNo());//发票号码
                invoiceRtnData.setJym(result.getInvoiceCheckCode());//校验码
                Date kprq = null;
                try {
                    kprq = DateUtils.parseDate(result.getInvoiceDate(),"yyyyMMddHHmmss");
                } catch (ParseException e) {
                    throw new RuntimeException(e);
                }
                invoiceRtnData.setKprq(kprq);//开票日期
                invoiceRtnData.setEwm(result.getInvoiceQrCode());//二维码
                invoiceRtnData.setSkm(result.getTaxControlCode());//税控码，发票类型为01/02时不返回此参数


            }else{
                throw new RuntimeException("接口返回数据异常");
            }
            invoiceRtn.setData(invoiceRtnData);
        } else {
            invoiceRtn.setSuccess(false);
            invoiceRtn.setMsg(response.getErrorResponse().getMessage());
        }

        return  invoiceRtn;
    }
}
